import { Inject, Provide } from '@midwayjs/core';
import { Context } from '@midwayjs/koa';
import { InjectEntityModel } from "@midwayjs/typeorm";
import { Repository } from "typeorm";
import { DictTypeEntity } from "@entity/system/dictType.entity";
import { DictDataEntity } from "@entity/system/dictData.entity";
import { ListDictTypeDTO, CreateDictTypeDTO, UpdateDictTypeDTO } from "@dto/system/dictType.dto";
import { DownloadExcelService } from "@service/common/downloadExcel";
import { resBuild } from "@utils/resBuild";
import { checkKeyIsExist } from "@utils/serviceHelp";
import { getOperator } from "@utils";
import { RedisService } from '@midwayjs/redis';
import { RedisEnum } from "@utils/enum";

@Provide()
export class DictTypeService {
  @Inject()
  ctx: Context;

  @Inject()
  redisService: RedisService;

  @Inject()
  downloadExcelService: DownloadExcelService;

  @InjectEntityModel(DictTypeEntity)
  dictTypeEntity: Repository<DictTypeEntity>;

  @InjectEntityModel(DictDataEntity)
  dictDataEntity: Repository<DictDataEntity>;

  // 列表
  async list(queryParams: ListDictTypeDTO) {
    const queryBuilder = this.dictTypeEntity.createQueryBuilder('entity');
    if(queryParams.dictName) {
      queryBuilder.andWhere(`entity.dictName like "%${queryParams.dictName}%"`)
    }
    if(queryParams.dictType) {
      queryBuilder.andWhere(`entity.dictType like "%${queryParams.dictType}%"`)
    }
    if(queryParams.status) {
      queryBuilder.andWhere(`entity.status = ${queryParams.status}`)
    }
    // 时间范围，包含全天
    if(queryParams["params[beginTime]"] && queryParams["params[endTime]"]) {
      queryBuilder.andWhere(`entity.createTime BETWEEN :beginTime AND :endTime`, {
        beginTime: queryParams["params[beginTime]"] + ' 00:00:00',
        endTime: queryParams["params[endTime]"] + ' 23:59:59',
      })
    }
    if(queryParams.pageNum && queryParams.pageSize) {
      queryBuilder.skip((queryParams.pageNum - 1) * queryParams.pageSize).take(queryParams.pageSize)
    }
    const [rows, total] = await queryBuilder.getManyAndCount()
    return resBuild.list(rows, total)
  }

  // 添加
  async create(dictType: CreateDictTypeDTO) {
    // 新增之前先判断是否已存在
    await checkKeyIsExist(this.dictTypeEntity,'dictType', dictType.dictType)
    const myEntity = this.dictTypeEntity.create(dictType);
    myEntity.setCreateBy(getOperator(this.ctx))
    await this.dictTypeEntity.save(myEntity);
    return resBuild.success()
  }

  // 删除，待优化，如果有子级，则不允许删除。同步删除redis
  async delete(dictId: string) {
    const ids = dictId.split(',').map(id => Number(id));
    await this.dictTypeEntity.delete(ids);
    return resBuild.success()
  }

  // 修改
  async update(dictType: UpdateDictTypeDTO) {
    const myEntity = this.dictTypeEntity.create(dictType);
    myEntity.setUpdateBy(getOperator(this.ctx))
    await this.dictTypeEntity.save(myEntity);
    return resBuild.success()
  }

  // 详情
  async detail(dictId: number) {
    const detailInfo = await this.dictTypeEntity.findOneBy({
      dictId,
    });
    return resBuild.data(detailInfo)
  }

  // 导出
  async export(queryParams: ListDictTypeDTO) {
    let headers = [
      { label: "字典编号", prop: "dictId", },
      { label: "字典名称", prop: "dictName", },
      { label: "字典类型", prop: "dictType", },
      { label: "状态", prop: "status", },
      { label: "备注", prop: "remark", },
      { label: "创建时间", prop: "createTime", width: 25 },
    ];
    const { rows } = await this.list(queryParams)
    return this.downloadExcelService.downloadExcel({
      headers: headers,
      data: rows,
      sheetName: '字典类型',
    });
  }

  // 字典选择框列表
  async optionSelect() {
    const allType = await this.dictTypeEntity.find();
    return resBuild.data(allType)
  }

  // 刷新缓存
  async refreshCache() {
    const allDictTypeList = await this.dictTypeEntity.find();
    for(const item of allDictTypeList) {
      const dictDataList = await this.dictDataEntity.find({
        select: ['cssClass','dictValue', 'dictLabel', 'dictSort',  "dictType", 'isDefault', 'status', 'listClass'],
        where: {
          dictType: item.dictType,
          status: '0'
        },
        order: {
          dictSort: 'ASC',
          createTime: 'DESC'
        }
      });
      await this.redisService.set(`${RedisEnum.SYS_DICT_KEY}${item.dictType}`, JSON.stringify(dictDataList));
    }
    return resBuild.success()
  }
}
